#include "device.h"
#include <string.h>

//昂瑞微的驱动库API
#include "rwip_config.h" // RW SW configuration
#include "peripheral.h"
#include "eeprom.h"
#include "eeprom_ota.h"
#include "cfg.h"

#define EFLASH_TRUE_SIZE (FLASH_SIZE_EEPROM - (4*1024))
#define EFLASH_FIRST_PROGRAM_ADDR    		(FLASH_BASE + (FLASH_ADDR_EEPROM - (4*1024)))
#define EFLASH_FIRST_PROGRAM_ADDR_OFFSET    (FLASH_ADDR_EEPROM - (4*1024))
#define EFLASH_FIRST_PROGRAM_VALUE   		(0x66666666) 

/**
  * @brief EEPROM读接口
  *
  * @note
  * @param  dev:虚拟设备
  * @param  data:读出数据保存的位置
  * @param  len:读出数据的字节数
  * @param  param:读的地址
  */
static int32_t EEPROM_Read(VirtualHardware_enum_t dev, void *data, uint32_t len, uint32_t param)
{
	if(dev == vEEPROM_0)
    {
		eeprom_read(param, data, len);
	}
  else if (dev == vEEPROM_1)
  {
    eeprom_ota_read(param, data, len);
  }
	return 0;
}

/**
  * @brief EEPROM写接口
  *
  * @note
  * @param  dev:虚拟设备
  * @param  data:写入的数据
  * @param  len:写入的数据字节数
  * @param  param:写入的地址
  */
static int32_t EEPROM_Write(VirtualHardware_enum_t dev, void *data, uint32_t len, uint32_t param)
{
	if(dev == vEEPROM_0)
    {
        eeprom_write(param, data, len);
  }
  if (dev == vEEPROM_1)
  {
    uint8_t cmd = (param >> 24);
    if (cmd == 1) //擦除全部OTA数据
    {
      eeprom_ota_erase_all();
    }
    else
    {
      eeprom_ota_write(param, data, len);
    }
  }
	return 0;
}

/**
  * @brief  EEPROM初始化
  *
  * @note
  */
static void EEPROM_Init(void)
{
    // uint8_t wtable[100],rtable[100];
    // uint8_t ret,i;
    uint32_t value = 0;

    // Enable flash
    sf_enable(HS_SF, 0);
    /* 1、初始化硬件 */
    value = *((volatile uint32_t *)EFLASH_FIRST_PROGRAM_ADDR);
    __OSAL_LOG("[eepromHal.c] first program flag: 0x%08X\r\n", value);
    if (value != EFLASH_FIRST_PROGRAM_VALUE)
    {
        __OSAL_LOG("[eepromHal.c] eeprom restore\r\n");
        value = EFLASH_FIRST_PROGRAM_VALUE;
        ee_restore();
        sf_write(HS_SF, 0, EFLASH_FIRST_PROGRAM_ADDR_OFFSET, (const uint8_t *)&value, sizeof(value));

    }
    else
    {
        __OSAL_LOG("[eepromHal.c] eeprom init\r\n");
        eeprom_init();
    }

    /* 2、将底层设备具体操作接口，挂到设备控制块里面 */
    Device_stu_t *dcb  = Device_GetDeviceCtrlBlock(vEEPROM);
    dcb->write = EEPROM_Write;
    dcb->read = EEPROM_Read;
    dcb->devParam = EFLASH_TRUE_SIZE;//TODO 实际有多大的EE就在这里填多大。

    // EEPROM_Read(vEEPROM_0,rtable,100,0);
    
    // printf("before\r\n");
    // for(i=0;i<100;i++)
    // {
    //   printf("%d ",rtable[i]);
    // }

    // for(i=0;i<100;i++)
    // {
    //     wtable[i] = i;  
    // }
    // EEPROM_Write(vEEPROM_0,wtable,100,0);

    // EEPROM_Read(vEEPROM_0,rtable,100,0); 

    // printf("after\r\n");
    // for(i=0;i<100;i++)
    // {
    //   printf("%d ",rtable[i]);
    // }  
    // ret = memcmp(wtable,rtable,100); 
    // if(ret == 0)
    // {
    //     printf("write success\r\n");
    // }
    // else
    // {
    //     printf("error\r\n");
    // }
    // while(1)
    // {
    //     co_delay_ms(500);
    //     Device_Write(vCPU_0,CPU_FEEDDOG,0,0);
    //     printf("code is run\r\n");
    // }   

}
INIT_DEVICE_EXPORT(EEPROM_Init);
